/*
 *****************************************************************************
 ** Date: 2007-1-2				Time: 11:48:07
 ** Author: Wang Bo (Brain Wang)
 ** Email: bow@hp.com 
 ** Network & Service Provider Industry
 ** HP Global Delivery China Center (GDCC)
 ** (C) Copyright 2006, Hewlett-Packard Company, All Rights Reserved.
 ** This software is the proprietary information of HP, Inc.  
 ** Use is subject to license terms.
 *****************************************************************************
 */
package com.hp.bon.sgw.util;

import java.io.File;
import java.io.IOException;

/**
 * Java Deamon Application Helper.
 * <p/>
 * The following is a example:
 * 
 * <pre>
 * public static void main(String[] args) throws Exception {
 * 	DeamonApplicationHelper appHelper = DeamonApplicationHelper.getInstance();
 * 	DBMonitorExample app = new DBMonitorExample();
 * 	app.start();
 * 	appHelper.waitExit();
 * 	app.exit();
 * }
 * </pre>
 * 
 * @author WangBo(Brain.Wang)
 * @version 1.0
 */
public class DeamonApplicationHelper {

	/**
	 * Get the singleton instance
	 * 
	 * @return instance
	 */
	static public DeamonApplicationHelper getInstance() {
		if (_instance == null) {
			StackTraceElement es[] = Thread.currentThread().getStackTrace();
			String main = es[es.length - 1].getClassName();
			_instance = new DeamonApplicationHelper(main);
		}
		return _instance;
	}

	static private DeamonApplicationHelper _instance;
	static private final String RUNNING_DIR = "./running";

	public DeamonApplicationHelper(String main) {
		try {
			_mainClassname = main;
			int i = main.lastIndexOf('.');
			if (i >= 0)
				_main = main.substring(i + 1);
			checkRunningStatus(true);
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(-1);
		}
	}

	private boolean checkRunningStatus(boolean exitIfRunning) {
		File fRunning = new File(RUNNING_DIR, _mainClassname + ".running");
		if (fRunning.exists()) {
			System.out
					.println(_main
							+ " maybe running,please ensure it's status!\nIf it isn't running,please delete the file:"
							+ fRunning.getAbsolutePath());
			if (exitIfRunning)
				System.exit(-1);
			return true;
		}
		return false;
	}

	/**
	 * Wait program exit create a running/program.running file,blocked,and check
	 * this file periodly,If the file is deleted,then return.
	 */
	public void waitExit() {
		File fStop = new File(RUNNING_DIR, _mainClassname + ".stop");
		File fRunning = new File(RUNNING_DIR, _mainClassname + ".running");
		if (fRunning.exists()) {
			System.out
					.println(_main
							+ " maybe running,please ensure it's status!\nIf it isn't running,please delete the file:"
							+ fRunning.getAbsolutePath());
			System.exit(-2);
		}
		fStop.delete();
		System.out.print("Create running control file:"
				+ fRunning.getAbsolutePath() + "...");
		try {
			fRunning.getParentFile().mkdirs();
			if (fRunning.createNewFile()) {
				System.out.println("success!");
				System.out.println("It can be stopped by creating stop file "
						+ fStop.getAbsolutePath() + " !");
			} else {
				throw new java.io.IOException(_main + ":create system file :"
						+ fRunning.getAbsolutePath() + " failed!");
			}
		} catch (java.io.IOException ex) {
			System.out.println(_main + ":create system file :"
					+ fRunning.getAbsolutePath() + "ERROR");
			ex.printStackTrace();
			System.exit(-3);
		}
		fRunning.deleteOnExit();
		while (!fStop.exists()) {
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
			}
		} // while
		System.out.println("Received a stop request. Exiting " + _main + "...");
		fStop.delete();
		fRunning.delete();
		//
		File dir = new File(RUNNING_DIR);
		String lists[] = dir.list();
		if (lists == null || lists.length < 1)
			dir.delete();
	}

	/**
	 * Request stop the application
	 */
	public void requestStop() {
		File fStop = new File(RUNNING_DIR, _main + ".stop");
		try {
			fStop.createNewFile();
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("Can NOT Create stop file "
					+ fStop.getAbsolutePath() + "!");
		}
	}

	private String _main;
	private String _mainClassname;
}
